package com.hzdh.account.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hpsf.Decimal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hzdh.account.commom.enums.ExpressCompanyEnums;
import com.hzdh.account.commom.enums.TypeEnums;
import com.hzdh.account.commom.exception.BusinessException;
import com.hzdh.account.entity.express.ToExpressCompany;
import com.hzdh.account.entity.login.User;
import com.hzdh.account.entity.pay.ToDayBook;
import com.hzdh.account.entity.pay.ToType;
import com.hzdh.account.repository.express.ToExpressCompanyMapper;
import com.hzdh.account.repository.goods.ToDayGoodsMapper;
import com.hzdh.account.repository.pay.ToDayBookMapper;
import com.hzdh.account.repository.pay.ToTypeMapper;
import com.hzdh.account.request.account.ToDayBookRequest;
import com.hzdh.account.response.account.ToDayBookResponse;
import com.hzdh.account.response.account.list.ToAccountListResponse;
import com.hzdh.account.service.AccountService;
import com.hzdh.account.service.TypeService;
import com.hzdh.account.service.UserService;
import com.hzdh.account.utils.DateUtils;
import com.hzdh.account.utils.GeneratorCodeUtils;
import com.hzdh.account.utils.NumberUtil;
import com.hzdh.account.utils.PinYinUtils;

@Service
public class AccountServiceImpl implements AccountService {

	private static Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class);
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private ToTypeMapper toTypeMapper;
	@Autowired
	private ToDayBookMapper toDayBookMapper;
	@Autowired
	private ToExpressCompanyMapper toExpressCompanyMapper;
	@Autowired
	private ToDayGoodsMapper toDayGoodsMapper;

	@Autowired
	private TypeService typeService;
	
	@Override
	public List<ToDayBookResponse> getToDayBook() {
		List<ToDayBook> dayBooks = toDayBookMapper.selectToDayBookAll(null);
		List<ToDayBookResponse> toDayBookResponses = new ArrayList<>(); 
		
		if(dayBooks != null && dayBooks.size() > 0) {
			for (ToDayBook toDayBook : dayBooks) {
				ToDayBookResponse toDayBookResponse = new ToDayBookResponse();
				BeanUtils.copyProperties(toDayBook, toDayBookResponse);
				toDayBookResponses.add(toDayBookResponse);
			}
		}
		return toDayBookResponses;
	}

	@Override
	public PageInfo<ToDayBook> getToDayBookPage(Map<String, String> paramMap) {
		
		PageInfo<ToDayBook> pageInfo = null;
		if (paramMap != null) {
			try {
				Integer pno=Integer.parseInt(String.valueOf(paramMap.get("page")));
				Integer pageSize=Integer.parseInt(String.valueOf(paramMap.get("limit")));
				PageHelper.startPage(pno, pageSize);
				
				List<ToDayBook> dayBooks = toDayBookMapper.selectToDayBookAll(paramMap);
				pageInfo = new PageInfo<>(dayBooks);
			} catch (Exception e) {
				logger.error("获取分页失败 = {}", e);
			}
		}
		
		return pageInfo;
	}

	@Override
	public PageInfo<ToAccountListResponse> getAccountListPage(Map<String, String> paramMap) {
		
		PageInfo<ToAccountListResponse> pageInfo = null;
		if (paramMap != null) {
			try {
				Integer pno=Integer.parseInt(String.valueOf(paramMap.get("page")));
				Integer pageSize=Integer.parseInt(String.valueOf(paramMap.get("limit")));
				PageHelper.startPage(pno, pageSize);
				
				List<ToAccountListResponse> dayBooks = toDayGoodsMapper.queryAccountGoodsList(paramMap);
				pageInfo = new PageInfo<>(dayBooks);
			} catch (Exception e) {
				logger.error("获取分页失败 = {}", e);
			}
		}
		
		return pageInfo;
	}

	@Override
	public ToDayBookResponse getToDayBookById(Long pkid) {
		if (pkid == null) {
			throw new BusinessException("数据查询错误,请联系管理员!");
		}
		ToDayBook toDayBook = toDayBookMapper.selectByPrimaryKey(pkid);
		//计算支出总金额
		ToDayBookResponse toDayBookResponse = new ToDayBookResponse();
		if (toDayBook != null) {
			List<ToDayBookResponse> dayBooks = getToDayBookByPayCode(toDayBook.getPayCode());
			BigDecimal sumPayMoney = new BigDecimal(0);
			for (ToDayBookResponse dayBookResponse : dayBooks) {
				sumPayMoney = NumberUtil.add(sumPayMoney, dayBookResponse.getPayMoney());
			}
			
			toDayBook.setSumPayMoney(sumPayMoney);
			BeanUtils.copyProperties(toDayBook, toDayBookResponse);
		}
		
		return toDayBookResponse;
	}

	@Override
	public List<ToDayBookResponse> getToDayBookByPayCode(String payCode) {
		if (payCode == null) {
			throw new BusinessException("数据查询错误,请联系管理员!");
		}
		List<ToDayBook>  dayBooks = toDayBookMapper.selectToDayBookByPaycode(payCode );
		List<ToDayBookResponse> dayBookResponses = new ArrayList<>();
		for (ToDayBook toDayBook : dayBooks) {
			ToDayBookResponse toDayBookResponse = new ToDayBookResponse();
			ToType type = toTypeMapper.selectToTypeByCode(toDayBook.getTypeCode());
			if (toDayBook != null) {
				toDayBook.setTypeName(type.getTypeName());
				BeanUtils.copyProperties(toDayBook, toDayBookResponse);
				dayBookResponses.add(toDayBookResponse);
			}
		}
		return dayBookResponses;
	}
	
	@Override
	public List<ToExpressCompany> getToExpressCompany() {
		
		return toExpressCompanyMapper.selectExpressCompanyAll();
	}

	@Override
	public void saveToDayBookInfo(ToDayBookRequest toDayBookRequest) {
		
		if (toDayBookRequest == null) throw new BusinessException("流水账单数据输入为空!");
		User sessionUser = userService.querySessionUser();
		// 生成支出编号
		String payCode = GeneratorCodeUtils.getSeqGeneratorCode("PAY");
		List<BigDecimal> payMoneys = toDayBookRequest.getPayMoney();
		if (payMoneys != null && payMoneys.size() > 0) {
			for (int i = 0; i < payMoneys.size(); i++) {
				ToDayBook toDayBook = new ToDayBook();
				toDayBook.setPayCode(payCode);
				toDayBook.setPayTime(DateUtils.strToFullDate(toDayBookRequest.getPayTime()));
				toDayBook.setPayUserName(toDayBookRequest.getUserName().equals(sessionUser.getRealName()) ? sessionUser.getUserId() : toDayBookRequest.getUserName());
				toDayBook.setCreateBy(sessionUser.getUserId());
				toDayBook.setCreateTime(new Date());
				toDayBook.setTypeCode(toDayBookRequest.getTypeCode().get(i));
				toDayBook.setPayMoney(toDayBookRequest.getPayMoney().get(i));
				if (TypeEnums.KDF.getCode().equals(toDayBookRequest.getTypeCode().get(i))) {
					toDayBook.setExpressCode(toDayBookRequest.getExpressCode());
				} else {
					toDayBook.setDescription(toDayBookRequest.getDescription().get(i));
				}
				toDayBook.setRemake(toDayBookRequest.getRemake().get(i));
				if (StringUtils.isNotBlank(toDayBookRequest.getTypeCode().get(i)) && toDayBookRequest.getPayMoney().get(i) != null) {
					ToDayBook dayBook = toDayBookMapper.selectToDayBookByPaycodeTypecode(payCode,toDayBookRequest.getTypeCode().get(i));
					int count = 0;
					if (dayBook != null) {
						toDayBook.setPkid(dayBook.getPkid());
						count = toDayBookMapper.updateByPrimaryKey(toDayBook);
						if (count == 0) {
							throw new BusinessException("当日流水数据保存失败!");
						}
					} else {
						count = toDayBookMapper.insertSelective(toDayBook );
						if (count == 0) {
							throw new BusinessException("当日流水数据保存失败!");
						}
					}
				}
				
				// 当支出类型为快递费时，描述选择快递公司为其他,快递表新增数据
				if (TypeEnums.KDF.getCode().equals(toDayBookRequest.getTypeCode().get(i)) 
						&& ExpressCompanyEnums.QT.getCode().equals(toDayBookRequest.getExpressCode())
						&& StringUtils.isNotBlank(toDayBookRequest.getRemake().get(i))) {
					saveExpressCompanyInfo(toDayBookRequest.getRemake().get(i));
				}
			}
		}
	}

	public void saveExpressCompanyInfo(String expressName) {
		
		ToExpressCompany toExpressCompany = new ToExpressCompany();
		toExpressCompany.setExpressCode(PinYinUtils.getFirstSpell(expressName, PinYinUtils.UPPERCASE_TEXT));
		toExpressCompany.setExpressName(expressName);
		toExpressCompany.setCreateBy(userService.querySessionUser().getUserId());
		toExpressCompany.setCreateTime(new Date());
		toExpressCompany.setUpdateBy(userService.querySessionUser().getUserId());
		toExpressCompany.setUpdateTime(new Date());
		
		ToExpressCompany expressCompany = toExpressCompanyMapper.selectExpressCompanyByExpressCode(toExpressCompany.getExpressCode());
		int count = 0;
		if (expressCompany != null) {
			toExpressCompany.setId(expressCompany.getId());
			count = toExpressCompanyMapper.updateByPrimaryKey(toExpressCompany);
			if (count == 0) {
				throw new BusinessException("快递公司信息数据保存失败!");
			}
		} else {
			count = toExpressCompanyMapper.insertSelective(toExpressCompany ); 
			if (count == 0) {
				throw new BusinessException("快递公司信息数据保存失败!");
			}
		}
		
	}
	
}
